package exception

import (
	"fmt"
	"reflect"
)

const (
	ErrCodeInvalidDataType  = 10000001
	ErrCodeInvalidDataValue = 10000002
)

type ErrorCode uint

type exception struct {
	ErrorCode ErrorCode
	Message   string
}

type Exception interface {
	Error() string
}

func (r exception) Error() string {
	if r.ErrorCode <= 0 {
		return ""
	}
	return fmt.Sprintf("%v[%v]", r.Message, r.ErrorCode)
}

func isExceptionStruct(item Exception) bool {
	return reflect.TypeOf(item).ConvertibleTo(reflect.TypeOf((*exception)(nil)))
}

func NewException(message string, code ErrorCode) Exception {
	return exception{
		Message:   message,
		ErrorCode: code,
	}
}

func ErrCode(e Exception) (ErrorCode, Exception) {
	if isExceptionStruct(e) {
		return e.(exception).ErrorCode, nil
	} else {
		return 999999999, NewException(fmt.Sprintf("Could not convert %v to ", e), ErrCodeInvalidDataType)
	}
}
